/*
  1. 概念
    定义类、接口、函数类型时，定义时不指定类型，使用时指定类型
  2. 泛型参数有默认值
    <T = string>
  3. 泛型参数约束
    <T extends Person4>
  4. 泛型工具类型
    Pick Omit Required Partial
  5. 应用
    React项目中：useState<number>(111)
    Vue3项目中：ref<number>(111) / reactive<{}>({})
*/

class Person<T> {
  name: T;
}

interface Person1<T> {
  name: T;
}

function Person2<T>(name: T) {}

class Person3<T = string> {
  name: T;
}

const p = new Person3();

interface Person4 {
  name: string;
  age: number;
}

function fn1<T>(person: T) {}

fn1<string>("str");
fn1<number>(111);

function fn2<T extends Person4>(person: T) {}

fn2({ name: "jack", age: 18, sex: "男" });

interface Person5 {
  readonly id: string;
  name: string;
  age: number;
  sex: string;
  hobby?: string[];
  address?: string;
}

// Pick 从某个对象类型中挑选一部分属性组成一个新的类型
type Person6 = Pick<Person5, "id" | "name">;

// Omit 从某个对象类型中排除一部分属性，剩下的属性组成一个新的类型
type Person7 = Omit<Person5, "id" | "name">;

// 将对象属性都变成必选属性
type Person8 = Required<Person5>;

// 将对象属性都变成可选属性
type Person9 = Partial<Person5>;
